<?php

namespace App\Core\Process;

use Psr\Log\LoggerInterface;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Contracts\Cache\ItemInterface;

trait Daemon
{
    protected $processExit = false;

    public static $pidKey = 'process_pids';

    /**
     * @var LoggerInterface
     */
    protected $logger;

    protected $handHook;

    protected function signalRegistry()
    {
        $pid = getmypid();
        $fileStorage = new FilesystemAdapter();
        /** @var ItemInterface $pidStorage */
        $pidStorage = $fileStorage->getItem(self::$pidKey);
        $pids = $pidStorage->get();
        if (empty($pids)) {
            $pidStorage->set([$pid]);
        } else {
            $pids[] = $pid;
            $pidStorage->set($pids);
        }
        $fileStorage->save($pidStorage);
        $this->_log("进程运行在 {$pid}");
        pcntl_signal(SIGINT, [$this, 'signalHandler']);
        pcntl_signal(SIGILL, [$this, 'signalHandler']);
        pcntl_signal(SIGPIPE, [$this, 'signalHandler']);
        pcntl_signal(SIGALRM, [$this, 'signalHandler']);
        pcntl_signal(SIGUSR1, [$this, 'signalHandler']);
        $this->_log("注册信号处理器");
    }

    public function setHandHook(callable $fn)
    {
        $this->handHook = $fn;
    }


    public function signalHandler($signo)
    {
        if ($signo == 14) {
            //忽略alarm信号
            $this->_log('忽略 信号14');
        } else {
            $this->_log("捕获 终止信号" . $signo);
            if ($signo == SIGINT) {
                $this->processExit = true;
                if (is_callable($this->handHook)) {
                    call_user_func($this->handHook);
                }
            }
        }
    }

    private function _log($message)
    {
        if ($this->logger) {
            $this->logger->info($message);
        }
    }

}